package com.orange.gateway.user;

import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.annotation.Order;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.time.Duration;

@Component
@Order(0)
@Slf4j
public class AuthFilter implements GlobalFilter {


    private final WebClient webClient;

    public AuthFilter(WebClient.Builder webClientBuilder) {
        this.webClient = webClientBuilder.build();
    }

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        String path = request.getPath().value();
//        String token = request.getQueryParams().getFirst("token");
        String token = request.getHeaders().getFirst("Authorization");
        // 跳过用户服务的接口
        if (path.contains("/user/login") || path.contains("/user/register")) {
            return chain.filter(exchange);
        }

        return validateToken(token)
                .flatMap(validationResponse -> {
                    System.out.println(validationResponse);
                    if (validationResponse.isValid()) {
                        // 添加用户信息到header
                        ServerHttpRequest newRequest = request.mutate()
                                .header("X-User-Account", validationResponse.getUserAccount())
                                .build();
                        return chain.filter(exchange.mutate().request(newRequest).build());
                    } else {
                        ServerHttpResponse response = exchange.getResponse();
                        response.setStatusCode(HttpStatus.UNAUTHORIZED);
                        String body = "{\"code\": 401, \"message\": \"Unauthorized\"}";
                        DataBuffer buffer = response.bufferFactory().wrap(body.getBytes());
                        return response.writeWith(Mono.just(buffer));
                    }
                }).onErrorResume(throwable -> {
                    log.info("Token验证服务调用失败: {}", throwable.getMessage());
                    return Mono.just( "认证服务暂时不可用").then();
                });



    }

    private Mono<TokenValidationResponse> validateToken(String token) {
        // token验证逻辑
        TokenValidationRequest request = new TokenValidationRequest(token);
        return webClient.post().uri("lb://user-service/user/validate")
                .contentType(MediaType.APPLICATION_JSON)
                .bodyValue(request)
                .retrieve()
                .onStatus(HttpStatusCode::is4xxClientError, response -> {
                    return Mono.error(new RuntimeException("客户端错误: " + response.statusCode()));
                })
                .onStatus(HttpStatusCode::is5xxServerError, response -> {
                    return Mono.error(new RuntimeException("服务器错误: " + response.statusCode()));
                })
                .bodyToMono(TokenValidationResponse.class)
                .timeout(Duration.ofSeconds(5)) // 5秒超时
                .doOnSuccess(response -> log.debug("Token验证请求成功发送"))
                .doOnError(error -> log.error("Token验证请求成功失败"));
    }

    private String extractUserId(String token) {
        // 从token中提取用户ID
        return "user123";
    }
}